package com.example.mactchoperator;


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.util.Random;

/**
 * @author user
 *
 *	si connexion
 *		envoi TCP
 *	sinon
 *		synchro tab2
 *			--> (tab2 envoi TCP)
 *
 *
 *
 */
public class SyncData {

	static ClientTCP clientNT = new ClientTCP("10.212.108.147", 6780); // 
//	static ClientTCP clientBT = new ClientTCP("10.212.123.245", 6787); //
	static ClientTCP clientBT = new ClientTCP("10.212.100.164", 6788); //

	static BluetoothMockServeur serveurtBT = new BluetoothMockServeur(6787); //


	static File dataPath = new File("Data/");
	static File logPath = new File("Data/log.txt");

	static ByteBuffer dataBuff  = ByteBuffer.allocate(512);

	static int TCPDataNotSent = 0;
	static int SyncDataSent = 0;

	static final byte NOTCONNECTED = (byte) 0xFFFF;
	static final byte CONNECTED    = (byte) 0xFFFE;
	static final byte NBSENT       = (byte) 0xFFFD;
	static boolean mainNotConnected = false;

	/**
	 * Methode a utiliser depuis les boutons de l'interface avec une table de bytes correspondants aux coups
	 * @param b
	 */
	public static void newMove(byte b) {
		writePersistance(b, true);
	}

	/**
	 * Methode a utiliser depuis le serveur Bluetooth pour la synchro, 
	 * les coups envoy� avec cette methode ne seront pas envoy� sur le r�seau, sauf si la tablette principale est d�connect�e
	 * @param b
	 */
	public static void SyncMove(byte b) {
		writePersistance(b, false);		
	}

	/**
	 * Methode a utiliser depuis le serveur Bluetooth,
	 * @param num
	 */

	public static void TCPDataSentViaSync(int num) {
		TCPDataNotSent -= num;
	}

	/**
	 * Methode a utiliser depuis le serveur Bluetooth, suivant les messages NOTCONNECTED (0xFFFF)/ CONNECTED (0xFFFE)
	 * @param num
	 */
	public static void setMainNotConnected(boolean b, int num) {
		mainNotConnected = b;
		TCPDataNotSent   = num;
	}


	///////////////////////////////////
	private static void writePersistance(byte b, boolean mainEntry) {
		dataBuff.put(b);
//		writeLocalPersistance(Byte.toString(b));

		if(clientNT.isConnected()) {
			if(mainEntry) {
				//				System.out.println("write " + Byte.toString(dataBuff.get(dataBuff.position() - 1)) + " pos = " + dataBuff.position());
				for (int i = dataBuff.position() - TCPDataNotSent - 1; i < dataBuff.position(); i++) {
					//					System.out.println("i = " + i);
					System.out.println("sending NT = " + TableData.moves[dataBuff.get(i) - 1]);
					clientNT.send(Byte.toString(dataBuff.get(i)));	
				}
				TCPDataNotSent = 0;
				if(clientBT.isConnected()) {
					clientBT.send(Byte.toString(CONNECTED) + ":" + TCPDataNotSent);	
				}
			}else{
				for (int i = dataBuff.position() - TCPDataNotSent + SyncDataSent; i < dataBuff.position(); i++) {
					clientNT.send(Byte.toString(dataBuff.get(i)));				
				}
				SyncDataSent++;
				if(clientBT.isConnected()) {
					clientBT.send(Byte.toString(NBSENT) + ":" + SyncDataSent);	
					SyncDataSent = 0;
				}

				TCPDataNotSent = 0;
			}
		}else{
//			System.out.println("not sent " + Byte.toString(dataBuff.get(dataBuff.position() - 1)));
			System.out.println("not co:sent " + Byte.toString(NOTCONNECTED) + ":" + TCPDataNotSent);
			TCPDataNotSent++;
			if(clientBT.isConnected()) {
				clientBT.send(Byte.toString(NOTCONNECTED) + ":" + TCPDataNotSent);
				for (int i = dataBuff.position() - SyncDataSent - 1; i < dataBuff.position(); i++) {
					System.out.println("sending BT = " + TableData.moves[dataBuff.get(i) - 1]);
					clientBT.send(Byte.toString(dataBuff.get(i)));				
				}

				SyncDataSent = 0;
			}else{
				SyncDataSent++;
			}
		}
//
//		if(clientBT.isConnected()) {
//			if(mainEntry) {
//				for (int i = dataBuff.position() - SyncDataNotSent - 1; i < dataBuff.position(); i++) {
//					System.out.println("sending BT = " + dataBuff.get(0));
//					clientBT.send(Byte.toString(dataBuff.get(i)));				
//				}
//
//				SyncDataNotSent = 0;
//
//			}
//		}else{
//			SyncDataNotSent++;
//		}
		
		if(!mainEntry && mainNotConnected && clientNT.isConnected()) {

			
		}else{
			//TCPDataNotSent++;
		}
	}


	private static void writeLocalPersistance(String c) {
		setupLocalPersistance(); 		

		Writer writer = null;
		try {
			writer = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(logPath, true), "utf-8"));
			writer.write(TableData.moves[Integer.parseInt(c)-1]);
			writer.write("\n");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {writer.close();} catch (Exception ex) {}
		}
	}


	private static void setupLocalPersistance() {
		if (!dataPath.exists()) {
			try{
				dataPath.mkdir();
			} catch(Exception e){
				e.printStackTrace();
			}       
		}

		if (!logPath.exists()) {
			try{
				logPath.createNewFile();
			} catch(Exception e){
				e.printStackTrace();
			}        
		}
	}


	/**
	 * @param args
	 */
	public static void main(String[] args) {		

		//table example

		Random g = new Random();
		
		while(!clientBT.isConnected())
			System.out.println(clientBT.isConnected());
		while(true)
			newMove((byte) (g.nextInt(11) + 1));


		//		System.out.println("!!1");
//		newMove(TableData.COUPDROIT);
//		//		System.out.println("!!2");
//		newMove(TableData.REVERS);
//		//		System.out.println("!!3");
//		newMove(TableData.ACE);
//		//		System.out.println("!!4");
//		newMove(TableData.PREMIERSERVICE);

		
//		System.out.println(Byte.toString(CONNECTED) + ":" + TCPDataNotSent);

	}

	public abstract static class TableData {
		public final static byte COUPDROIT 			= 0x01;
		public final static byte REVERS    			= 0x02;
		public final static byte ACE      			= 0x03;
		public final static byte PREMIERSERVICE		= 0x04;
		public final static byte DEUXIEMESERVICE	= 0x05;
		public final static byte LOB 				= 0x06;
		public final static byte AMORTI 			= 0x07;
		public final static byte GAGNANT 			= 0x08;
		public final static byte FAUTE 				= 0x09;
		public final static byte DOUBLEFAUTE		= 0x0A;
		public static final byte SMASH				= 0x0B;

		public final static String[] moves = { "Coup droit", "Revers", "Ace", "Premier Service", "Deuxieme Service", "Lob", "Amorti", "Gagnant", "Faute", "Double Faute", "Smash" };
		
	}

}
